iT邦幫忙

2022 iThome 鐵人賽

DAY 24
0
Web 3

2022最火話題NFT到底是什麼?釐清NFT和虛擬貨幣以及區塊鏈的關係,做出自己專屬的NFT!!系列 第 24

Day 24 | 懶人也能智能互動!沒有程式基礎也能駕馭智能合約(一)撰寫+編譯合約

  • 分享至 

  • xImage
  •  

前言

講了那麼多,大家手應該很癢了吧,都等不急來實作了吧!!我們今天就來先小試身手一下吧!帶大家進入智能合約的基礎程式解說!/images/emoticon/emoticon12.gif


正文

我們這次合約部屬的流程如下:

撰寫合約 > 編譯合約 > 將合約部署到測試鏈上 > 利用IPFS將NFT的Metadata補上並mint NFT > 部署到正式鏈上

|Openzeppelin|

我們先打開Openzeppelin,我們最大的福音
https://ithelp.ithome.com.tw/upload/images/20221004/20152558Du3dnVEFGt.png

點選 START
https://ithelp.ithome.com.tw/upload/images/20221004/20152558EuO5lJONsg.png
點選Wizard、點選ERC-721,修改一下Token ID,再將自己需要的功能勾選起來、就可以打開Remix編譯了

|Remix|

-宣告-

// SPDX-License-Identifier: MIT 大家都可以使用在自己的合約上,代表開源

pragma solidity ^0.8.4; // solidity版本

import "@openzeppelin/contracts@4.7.3/token/ERC721/ERC721.sol";

//使用ERC-721功能

import "@openzeppelin/contracts@4.7.3/token/ERC721/extensions/ERC721Enumerable.sol";

//使用ERC-721 Enumerable擴充功能

import "@openzeppelin/contracts@4.7.3/token/ERC721/extensions/ERC721URIStorage.sol";

//使用ERC-721 URIStorage擴充功能

import "@openzeppelin/contracts@4.7.3/utils/Counters.sol";//持續追蹤NFT功能

大致上前面的宣告就是這樣

   import "@openzeppelin/contracts@4.7.3/access/Ownable.sol";

這段要刪掉,等等會講到,單壓

  ``` 
  contract KNFT is ERC721, ERC721Enumerable, ERC721URIStorage {
  
  //這邊因為要讓每個人都可以mint,因此我們將ownable方法刪除
  
using Counters for Counters.Counter;//用來追蹤NFT

Counters.Counter private _tokenIdCounter;//此功能只能在這個智能合約使用,繼承的合約不行使用和讀取

uint256 MAX_SUPPLY = 2;//NFT最大供應量

constructor() ERC721("KNFT", "K") {}//ERC-721的資料結構(名稱,代號)
```

這邊就是一些基本的設置,不過要注意的是,因為剛剛把onlyOwner去掉了,宣告使用Owner的方法也不會使用到,因此前面的有關Owner都可以刪掉,接下來後面一長串也就是OpenZeppelin幫我們上的功能,比較需要注意的就是SafeMintTokenURI

-function-

function safeMint(address to, string memory uri) public  {

//(錢包地址,之後要填入的MetaData),這邊public是公開的,和後面的onlyowner牴觸,所以刪掉

        uint256 tokenId = _tokenIdCounter.current();
        
        require (tokenId < MAX_SUPPLY , "All NFT have been minted");
        
        //這邊我追們加一個require語法,當NTF被mint完後,就會顯示已售完
        
        _tokenIdCounter.increment();
        
        _safeMint(to, tokenId);//這邊(to 你的錢包地址 , token id)
        
        _setTokenURI(tokenId, uri);
    }

這邊比較特別的是,因為Public是全公開的,為了確保每個人都可以mint,因此我們需要將後面onlyOwner去掉。
為什麼是 < 不是 <= ,是因為TokenID是從0開始

//TokenTransfer
    function _beforeTokenTransfer(address from, address to, uint256 tokenId)
        internal//internal 比較像pravite但是繼承的合約他可以讀取和使用
        override(ERC721, ERC721Enumerable)
    {
        super._beforeTokenTransfer(from, to, tokenId);
    }
//Burn
    function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
        super._burn(tokenId);
    }
//TokenURI 
    function tokenURI(uint256 tokenId)
        public
        view//讀取區塊鏈上的資料,在自己的錢包讀取不需要支付gas
        override(ERC721, ERC721URIStorage)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }
//supportsInterface
    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721Enumerable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

到這邊合約就大致上撰寫完畢了,完整和約我傳在下面,明天再來帶大家實作如何傳到測試鏈上並使用水龍頭


完整合約

// SPDX-License-Identifier: MIT 大家都可以使用在自己的合約上,代表開源
pragma solidity ^0.8.4; // solidity版本

import "@openzeppelin/contracts@4.7.3/token/ERC721/ERC721.sol";//使用ERC-721功能
import "@openzeppelin/contracts@4.7.3/token/ERC721/extensions/ERC721Enumerable.sol";//使用ERC-721 Enumerable擴充功能
import "@openzeppelin/contracts@4.7.3/token/ERC721/extensions/ERC721URIStorage.sol";//使用ERC-721 URIStorage擴充功能
import "@openzeppelin/contracts@4.7.3/utils/Counters.sol";//持續追蹤NFT功能

contract KNFT is ERC721, ERC721Enumerable, ERC721URIStorage {//這邊因為要讓每個人都可以mint,因此我們將ownable方法刪除
    using Counters for Counters.Counter;//用來追蹤NFT

    Counters.Counter private _tokenIdCounter;//此功能只能在這個智能合約使用,繼承的合約不行使用和讀取
    uint256 MAX_SUPPLY = 2;//NFT最大供應量
    constructor() ERC721("KNFT", "K") {}//ERC-721的資料結構(名稱,代號)

//safeMint

    function safeMint(address to, string memory uri) public  {//(錢包地址,之後要填入的MetaData),這邊public是公開的,和後面的onlyowner牴觸,所以刪掉
        uint256 tokenId = _tokenIdCounter.current();
        require (tokenId < MAX_SUPPLY , "All NFT have been minted");//這邊我追們加一個require語法,當NTF被mint完後,就會顯示已售完
        _tokenIdCounter.increment();
        _safeMint(to, tokenId);//這邊(to 你的錢包地址 , token id)
        _setTokenURI(tokenId, uri);//()
    }

    // The following functions are overrides required by Solidity.

//TokenTransfer
    function _beforeTokenTransfer(address from, address to, uint256 tokenId)
        internal//internal 比較像pravite但是繼承的合約他可以讀取和使用
        override(ERC721, ERC721Enumerable)
    {
        super._beforeTokenTransfer(from, to, tokenId);
    }
//Burn
    function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
        super._burn(tokenId);
    }
//TokenURI 
    function tokenURI(uint256 tokenId)
        public
        view//讀取區塊鏈上的資料,在自己的錢包讀取不需要支付gas
        override(ERC721, ERC721URIStorage)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }
//supportsInterface
    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721Enumerable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}


上一篇
Day 23 | 智能合約工具介紹 (三) 測試篇 Faucet & IPFS
下一篇
Day 25 | 懶人也能智能互動!沒有程式基礎也能駕馭智能合約(二)測試鏈+水龍頭
系列文
2022最火話題NFT到底是什麼?釐清NFT和虛擬貨幣以及區塊鏈的關係,做出自己專屬的NFT!!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言